package com.itcast.spring6.aop.bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;

/**
 * java aop 判断模式 目标过滤示例
 * 判断来源
 *  类型 class
 *  方法 method
 *  注解 annotation
 *  参数 parameter
 *  异常 exception
 * @author zhangtian105
 * @date 2023/5/5
 * @apiNote
 */
@Slf4j
public class AopPredicateTest {
    public static void main(String[] args) throws ClassNotFoundException {
        String targetClassName = "com.itcast.spring6.aop.bean.EchoService" ;
        // 获取当前线程classloader
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        // 获取目标类
        Class<?> clazz = classLoader.loadClass(targetClassName) ;
        // 方法定义：String echo(String msg) throws NullPointerException
        // spring反射工具类 获取到方法
        Method targetMethod = ReflectionUtils.findMethod(clazz, "echo", String.class) ;

        log.info("targetMethod is: {}", targetMethod);

        // 查找方法 throw 类型为NullPointerException
        ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
            @Override
            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
                log.info("仅输出 NullPointerException method is: {}", method);
            }
        }, new ReflectionUtils.MethodFilter(){
            @Override
            public boolean matches(Method method) {
                Class[] exceptionTypes = method.getExceptionTypes();
                return exceptionTypes.length == 1
                        && NullPointerException.class.isAssignableFrom(exceptionTypes[0]);
            }
        });
    }
}
